home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ohlcpio.zip / COPYOUT.C < prev    next >
C/C++ Source or Header  |  1990-07-07  |  7KB  |  232 lines

  1. /* copyout.c - cpio copy out sub-function.
  2.    Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #ifndef S_IFLNK
  22. #define lstat stat
  23. #endif
  24. #include <errno.h>
  25. extern int errno;
  26. #include <fcntl.h>
  27. #include <sys/file.h>
  28. #ifdef USG
  29. #include <time.h>
  30. #include <string.h>
  31. #else
  32. #include <sys/time.h>
  33. #include <strings.h>
  34. #endif
  35. #include "cpio.h"
  36. #include "dstring.h"
  37. #include "extern.h"
  38.  
  39. /* Write out header FILE_HDR, including the file name, to file
  40.    descriptor OUT_DES. */
  41.  
  42. void
  43. write_out_header (file_hdr, out_des)
  44.      struct cpio_header *file_hdr;
  45.      int out_des;
  46. {
  47.   if (portability_flag)
  48.     {
  49.       char ascii_header[78];
  50.  
  51.       sprintf (ascii_header,
  52.            "%06o%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o",
  53.            file_hdr->h_magic & 0xFFFF, file_hdr->h_dev & 0xFFFF,
  54.            file_hdr->h_ino & 0xFFFF, file_hdr->h_mode & 0xFFFF,
  55.            file_hdr->h_uid & 0xFFFF, file_hdr->h_gid & 0xFFFF,
  56.            file_hdr->h_nlink & 0xFFFF, file_hdr->h_rdev & 0xFFFF,
  57.            file_hdr->h_mtime, file_hdr->h_namesize & 0xFFFF,
  58.            file_hdr->h_filesize);
  59.       copy_buf_out (ascii_header, out_des, 76);
  60.  
  61.       /* Write file name to output.  */
  62.       copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
  63.     }
  64.   else
  65.     {
  66.       /* Word align the output. */
  67.       if (output_size & 1)
  68.     copy_buf_out ("", out_des, 1);
  69.  
  70.       file_hdr->h_mtimes[0] = file_hdr->h_mtime >> 16;
  71.       file_hdr->h_mtimes[1] = file_hdr->h_mtime & 0xFFFF;
  72.  
  73.       file_hdr->h_filesizes[0] = file_hdr->h_filesize >> 16;
  74.       file_hdr->h_filesizes[1] = file_hdr->h_filesize & 0xFFFF;
  75.  
  76.       /* Output the file header. */
  77.       copy_buf_out ((char *) file_hdr, out_des, 26);
  78.  
  79.       /* Write file name to output.  */
  80.       copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
  81.  
  82.       /* Word align the output. */
  83.       if (file_hdr->h_namesize % 2)
  84.     copy_buf_out ("", out_des, 1);
  85.     }
  86. }
  87.  
  88. /* Read a list of file names from the standard input
  89.    and write a cpio collection on the standard output.
  90.    The format of the header depends on the compatibility (-c) flag.  */
  91.  
  92. void
  93. process_copy_out ()
  94. {
  95.   int res;            /* Result of functions.  */
  96.   dynamic_string input_name;    /* Name of file read from stdin.  */
  97.   long times[2];        /* For resetting file times after copy.  */
  98.   struct stat file_stat;    /* Stat record for file.  */
  99.   struct cpio_header file_hdr;    /* Output header information.  */
  100.   int in_file_des;        /* Source file descriptor. */
  101.   int out_file_des;        /* Output file descriptor. */
  102.  
  103.   /* Initialize copy out. */
  104.   ds_init (&input_name, 128);
  105.   file_hdr.h_magic = 070707;
  106.  
  107.   /* Check whether the output file might be a tape.  */
  108.   out_file_des = fileno (stdout);
  109.   if (fstat (out_file_des, &file_stat))
  110.     error (1, errno, "standard output is closed");
  111.   output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR
  112.                || (file_stat.st_mode & S_IFMT) == S_IFBLK);
  113.   output_is_seekable = ((file_stat.st_mode & S_IFMT) == S_IFREG);
  114.  
  115.   /* Copy files with names read from stdin.  */
  116.   while (ds_fgets (stdin, &input_name) != NULL)
  117.     {
  118.       /* Check for blank line.  */
  119.       if (input_name.ds_string[0] == 0)
  120.     {
  121.       error (0, 0, "blank line ignored");
  122.       continue;
  123.     }
  124.  
  125.       /* Process next file. */
  126.       if ((*xstat) (input_name.ds_string, &file_stat) < 0)
  127.     error (0, errno, "%s", input_name.ds_string);
  128.       else
  129.     {
  130.       /* Set values in output header.  */
  131.       file_hdr.h_dev = file_stat.st_dev;
  132.       file_hdr.h_ino = file_stat.st_ino;
  133.       file_hdr.h_mode = file_stat.st_mode;
  134.       file_hdr.h_uid = file_stat.st_uid;
  135.       file_hdr.h_gid = file_stat.st_gid;
  136.       file_hdr.h_nlink = file_stat.st_nlink;
  137.       file_hdr.h_rdev = file_stat.st_rdev;
  138.       file_hdr.h_mtime = file_stat.st_mtime;
  139.       file_hdr.h_filesize = file_stat.st_size;
  140.       file_hdr.h_namesize = ds_strlen (&input_name) + 1;
  141.       file_hdr.h_name = input_name.ds_string;
  142.  
  143.       /* Copy the named file to the output.  */
  144.       switch (file_hdr.h_mode & S_IFMT)
  145.         {
  146.         case S_IFREG:
  147.           in_file_des = open (input_name.ds_string, O_RDONLY, 0);
  148.           if (in_file_des < 0)
  149.         {
  150.           error (0, errno, "%s", input_name.ds_string);
  151.           continue;
  152.         }
  153.  
  154.           write_out_header (&file_hdr, out_file_des);
  155.           copy_files (in_file_des, out_file_des, file_hdr.h_filesize);
  156.           close (in_file_des);
  157.           if (reset_time_flag)
  158.         {
  159.           times[0] = file_stat.st_atime;
  160.           times[1] = file_stat.st_mtime;
  161.           if (utime (file_hdr.h_name, times) < 0)
  162.             error (0, errno, "%s", file_hdr.h_name);
  163.         }
  164.           break;
  165.  
  166.         case S_IFDIR:
  167.           file_hdr.h_filesize = 0;
  168.           write_out_header (&file_hdr, out_file_des);
  169.           break;
  170.  
  171.         case S_IFCHR:
  172.         case S_IFBLK:
  173. #ifdef S_IFSOCK
  174.         case S_IFSOCK:
  175. #endif
  176. #ifdef S_IFIFO
  177.         case S_IFIFO:
  178. #endif
  179.           file_hdr.h_filesize = 0;
  180.           write_out_header (&file_hdr, out_file_des);
  181.           break;
  182.  
  183. #ifdef S_IFLNK
  184.         case S_IFLNK:
  185.           {
  186.         char *link_name = (char *) xmalloc (file_stat.st_size);
  187.  
  188.         if (readlink (input_name.ds_string, link_name,
  189.                   file_stat.st_size) < 0)
  190.           {
  191.             error (0, errno, "%s", input_name.ds_string);
  192.             free (link_name);
  193.             continue;
  194.           }
  195.         write_out_header (&file_hdr, out_file_des);
  196.         copy_buf_out (link_name, out_file_des, file_stat.st_size);
  197.         free (link_name);
  198.           }
  199.           break;
  200. #endif
  201.  
  202.         default:
  203.           error (0, 0, "%s: unknown file type", input_name.ds_string);
  204.         }
  205.  
  206.       if (verbose_flag)
  207.         fprintf (stderr, "%s\n", input_name.ds_string);
  208.     }
  209.     }
  210.  
  211.   /* The collection is complete; append the trailer.  */
  212.   file_hdr.h_filesize = 0;
  213.   file_hdr.h_namesize = 11;
  214.   file_hdr.h_name = "TRAILER!!!";
  215.   write_out_header (&file_hdr, out_file_des);
  216.  
  217.   /* Fill up the output block.  */
  218.   while (output_size < io_block_size)
  219.     {
  220.       copy_buf_out (output_buffer, out_file_des,
  221.             (2 * output_size < io_block_size) ?
  222.             output_size : io_block_size - output_size);
  223.     }
  224.   empty_output_buffer (out_file_des);
  225.   finish_output_file ("standard output", out_file_des);
  226.   res = output_bytes / io_block_size;
  227.   if (res == 1)
  228.     fprintf (stderr, "1 block\n");
  229.   else
  230.     fprintf (stderr, "%d blocks\n", res);
  231. }
  232.